#ifndef __EC_BSP_AHT21_DRIVER_H
#define __EC_BSP_AHT21_DRIVER_H

#include "main.h"
#define OS_SUPPORTING
#define AHT21_REG_READ_ADDR 0x7
// #define HARDWARE_IIC

/* Return value from function  */
typedef enum
{
    AHT21_OK               = 0,           /* Operation completed successfully  */
    AHT21_ERROR            = 1,           /* Run-time error without case matched */
    AHT21_ERRORTIMEOUT     = 2,           /* operation failled with timeout */
    AHT21_ERRORRESOURCE    = 3,           /* Resource not available */
    AHT21_ERRORPARAMETER   = 4,           /* Parameter error */
    AHT21_ERRORNOMEMORY    = 5,           /* Out of memory */
    AHT21_ERRORISR         = 6,           /* Not allowed in ISR context */
    AHT21_RESERVED         = 0x7FFFFFFF,  /* Reserved */
}aht21_status_t; 


// ************************* Defines **************************************//

/* ************************* Declaring ********************************** */

#ifndef HARDWARE_IIC   /* True : Software IIC */
typedef struct
{
    aht21_status_t(*pf_iic_init)          (void*);  /* IIC init interf */
    aht21_status_t(*pf_iic_deinit)        (void*);  /* IIC deinit interf */
    aht21_status_t(*pf_iic_start)         (void*);  /* IIC start interf */
    aht21_status_t(*pf_iic_stop)          (void*);  /* IIC stop interf */
    aht21_status_t(*pf_iic_wait_ack)      (void*);  /* IIC wait_ack interf */
    aht21_status_t(*pf_iic_send_ack)      (void*);  /* IIC send_ack interf */
    aht21_status_t(*pf_iic_send_no_ack)   (void*);  /* IIC send_no_ack interf */
    aht21_status_t(*pf_iic_send_byte)     (void*);  /* IIC send_byte interf */
    aht21_status_t(*pf_iic_receive_byte)  (void*);  /* IIC receive_byte interf */
  
    aht21_status_t(*pf_critical_enter)    (void*);  /* enter critical interf */
    aht21_status_t(*pf_critical_exit)     (void*);  /* exit critical interf */
}iic_driver_interface_t;
#endif/* end of HARDWARE_IIC */


/* ************************* Declaring ********************************** */
#ifdef HARDWARE_IIC
typedef struct
{
    uint8_t (*pfiic_init)              (void*);
    uint8_t (*pfiic_deinit)            (void*);
    void    (*pfiic_send_ack)          (void*);
    void    (*pfiic_send_no_ack)       (void*);
    void    (*pfiic_send_byte)         (void *,uint8_t);
    uint8_t (*pfiic_receive_byte)      (void*);
}iic_driver_interface_t;
#endif /* END OF HARDWARE_IIC */

/* From Core Layer: TimeBase  */
typedef struct
{
    uint32_t (*pf_get_tick_count)(void);   /* Get Tick number interf */
} timebase_interface_t;

/* From OS Layer: OS_Delay */
#ifdef OS_SUPPORTING
typedef struct 
{
    void (*pf_rtos_yield)(const uint32_t); /* OS Not-Blocking Delay */
}yield_interface_t;

#endif /* END OF OS_SUPPORTING */

/* ************************* Declaring ********************************** */
/* Aht21_Hal_driver instance class */
typedef struct
{
    iic_driver_interface_t *p_iic_driver_instance;
    timebase_interface_t   *p_timebase_instance;
    yield_interface_t      *p_yield_instance;

    uint8_t (*pfinst)(
                                void                   * const paht21_instance,
                                iic_driver_interface_t * const piic_driver_instance,
                                timebase_interface_t   * const ptimebase_instance,
                                yield_interface_t      * const pyield_instance);

    uint8_t (*pfinit)           (void * const);
    uint8_t (*pfdeinit)         (void * const);
    uint8_t (*pfread_id)        (void * const);
    uint8_t (*pfread_temp)      (void * const,
                                 float * const temp);
    uint8_t (*pfread_humidity)  (void * const,
                                 float * const humi);
    uint8_t (*pfsleep)          (void * const);
    uint8_t (*pfwakeup)         (void * const);
}bsp_aht21_driver_t;


uint8_t (*pfinst)(
                                void                   * const paht21_instance,
                                iic_driver_interface_t * const piic_driver_instance,
                                timebase_interface_t   *const ptimebase_instance,
                                yield_interface_t      *const pyield_instance);

// *************************** Declaring ***************************************


#endif
